package com.lz.yz.outing.service.impl;

import com.lz.yz.base.entity.ReturnValue;
import com.lz.yz.order.entity.Orders;
import com.lz.yz.order.enumeration.OrderStatus;
import com.lz.yz.order.service.OrdersService;
import com.lz.yz.outing.config.ConstantConfig;
import com.lz.yz.outing.config.InitConfig;
import com.lz.yz.outing.config.WechatConfig;
import com.lz.yz.outing.entity.RefundResult;
import com.lz.yz.outing.entity.RefundVo;
import com.lz.yz.outing.enumeration.SettingType;
import com.lz.yz.outing.service.WechatService;
import com.lz.yz.outing.util.HttpsRequest;
import com.lz.yz.outing.util.Signature;
import com.lz.yz.outing.util.ToolUtil;
import com.lz.yz.outing.util.Util;
import com.lz.yz.reward.dao.RewardMapper;
import com.lz.yz.reward.entity.Reward;
import com.lz.yz.reward.enumeration.RewardStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Service
public class WechatServiceImpl implements WechatService {

    Logger log = LoggerFactory.getLogger(WechatServiceImpl.class);
    @Autowired
    private InitConfig initConfig;
    @Autowired
    private ConstantConfig constantConfig;
    @Autowired
    private Signature signature;

    @Autowired
    OrdersService ordersService;

    @Autowired
    RewardMapper rewardMapper;

    /**
     * 微信退款
     */
    @Override
    public ReturnValue wechatPayRefund(String orderNo){
        try {
            Orders  orderBean = ordersService.findBy("orderNo",orderNo);
            if(orderBean==null){
                return ReturnValue.generateFalseReturnValue("没有查到该订单");
            }
            Map<String, Object> map = new HashMap<>();
            Orders order = new Orders();
            BeanUtils.copyProperties(orderBean,order);
            //生成随机数
            String random = ToolUtil.createRandomNumber(32);

            map.put("out_trade_no",orderNo);
            map.put("total_fee",order.getTotalPrice().multiply(new BigDecimal(100)).intValue());
            map.put("appid", initConfig.getWechatAppid());
            map.put("mch_id", initConfig.getMchId());
            map.put("nonce_str", random);
            map.put("refund_fee", order.getTotalPrice().multiply(new BigDecimal(100)).intValue());
            map.put("out_refund_no", "tk"+orderNo);
            String sign = signature.getSign(map,initConfig.getGzhKey());

            RefundVo reqData = new RefundVo();
            reqData.setAppid(initConfig.getWechatAppid());
            reqData.setMch_id(initConfig.getMchId());
            reqData.setNonce_str(random);
            reqData.setOut_trade_no((String) map.get("out_trade_no"));
            reqData.setTotal_fee(Integer.valueOf(map.get("total_fee").toString()));
            reqData.setRefund_fee(Integer.valueOf(map.get("refund_fee").toString()));
            reqData.setOut_refund_no("tk"+orderNo);
            reqData.setSign(sign);

            String result = HttpsRequest.executeBySslPost(initConfig.getMchId(), WechatConfig.ORDERREFUND_URL, reqData,constantConfig.getSetting().equals(SettingType.PROD.value())?"apiclient_cert.p12":"apiclient_cert_test.p12");

            RefundResult payResData = (RefundResult) Util.getObjectFromXML(result, RefundResult.class);
            if (payResData == null || payResData.getReturn_code() == null) {
                log.warn("【支付失败】支付请求逻辑错误，请仔细检测传过去的每一个参数是否合法，或是看API能否被正常访问:" + result);
                return ReturnValue.generateFalseReturnValue(result);
            }
            if (payResData.getReturn_code().equals("FAIL")) {
                //注意：一般这里返回FAIL是出现系统级参数错误，请检测Post给API的数据是否规范合法
                log.warn("【支付失败】支付API系统返回失败，请检测Post给API的数据是否规范合法:" + result);
                return ReturnValue.generateFalseReturnValue(result);
            } else {
                //--------------------------------------------------------------------
                //收到API的返回数据的时候得先验证一下数据有没有被第三方篡改，确保安全
                //--------------------------------------------------------------------
                if (!signature.checkIsSignValidFromResponseString(result,initConfig.getGzhKey())) {
                    log.warn("【支付失败】支付请求API返回的数据签名验证失败，有可能数据被篡改了:" + result);
                    return ReturnValue.generateFalseReturnValue(result);
                }
                //获取错误码
                String errorCode = payResData.getErr_code();
                //获取错误描述
                String errorCodeDes = payResData.getErr_code_des();
                if (payResData.getResult_code().equals("SUCCESS")) {
                    //--------------------------------------------------------------------
                    //1)退款成功 修改订单状态
                    //--------------------------------------------------------------------
                    ordersService.update(new Orders(orderBean.getId(), OrderStatus.REFUND.getStatusValue()));
                    rewardMapper.updateByPrimaryKeySelective(new Reward(orderBean.getObjectiveId(), RewardStatus.CANCEL.getStatusValue()));
                    return ReturnValue.generateTrueReturnValue();
                } else {
                    log.error("err_code", errorCode);
                    log.error("err_code_des", errorCodeDes);
                    return ReturnValue.generateFalseReturnValue("业务返回失败",Integer.valueOf(errorCode));
                }
            }

        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return ReturnValue.generateFalseReturnValue("业务返回失败");
    }

}
